package com.mobile.tools;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.hibernate.LazyInitializationException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.mobile.struts.action.tools.AssociateTableInfo;
import com.mobile.struts.action.tools.ClassDelegate;

public class JsonHelp<T> {
	
	private final Logger LOGGER = LogManager.getLogger(JsonHelp.class);
	
	/**
	 * Json化对象
	 * @param list			要格式化对象数组
	 * @param strings		对象属性名称数组
	 * @return				格式为:"[{},{}]"的字符串
	 */
	public String getJson(List<T> list,String[] strings ){
		if(strings==null||strings.length==0){
			return getJson(list);
		}
		
		StringBuffer json=new StringBuffer();
		PropertyDescriptor pd=null;
		int i=0;
		json.append("[");
		try {
			for(T obj:list){
				json.append("{");
				int j=0;
				for(String str:strings){
					String value=null;
					pd=new PropertyDescriptor(str,obj.getClass());
					if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
						value=pd.getReadMethod().invoke(obj).toString();
					}
					
					json.append(str+":'"+value+"'");
					
					if(j+1!=strings.length){
						json.append(",");
					}
					j++;
				}
				if(i+1==list.size()){
					json.append("}");
				}else{
					json.append("},");
				}
				i++;
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		json.append("]");
		return json.toString();
	}
	/**
	 * Json化对象
	 * @param list			要格式化对象数组
	 * @param map			map中key为T的属性，value为json中的属性
	 * @return				格式为:"[{},{}]"的字符串
	 */
	public String getJson(List<T> list,Map<String,String> map){
		if(map==null||map.size()==0){
			return getJson(list);
		}
		
		StringBuffer json=new StringBuffer();
		PropertyDescriptor pd=null;
		int i=0;
		json.append("[");
		try {
			for(T obj:list){
				json.append("{");
				int j=0;
				for(Map.Entry<String, String> entry:map.entrySet()){
					String value=null;
					pd=new PropertyDescriptor(entry.getKey(),obj.getClass());
					if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
						value=pd.getReadMethod().invoke(obj).toString();
					}
					
					json.append(entry.getValue()+":'"+value+"'");
					
					if(j+1!=map.size()){
						json.append(",");
					}
					j++;
				}
				if(i+1==list.size()){
					json.append("}");
				}else{
					json.append("},");
				}
				i++;
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		json.append("]");
		return json.toString();
	}
	
	/**
	 * Json化对象
	 * @param list			要格式化对象数组
	 * @param strings		对象属性名称数组
	 * @return				格式为:"[{},{}]"的字符串
	 */
	public String getJson(List<T> list,T pojo){
		StringBuffer json=new StringBuffer();
		
		int i=0;
		json.append("[");
		try {
			BeanInfo beanInfo=Introspector.getBeanInfo(pojo.getClass(),Object.class);
			
			PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
			for(T obj:list){
				json.append("{");
				int j=0;
				for(PropertyDescriptor pd:pds){
					String value=null;

					if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
						value=pd.getReadMethod().invoke(obj).toString();
					}
					
					json.append(pd.getName()+":'"+value+"'");
					
					if(j+1!=pds.length){
						json.append(",");
					}
					j++;
				}
				if(i+1==list.size()){
					json.append("}");
				}else{
					json.append("},");
				}
				i++;
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		json.append("]");
		return json.toString();
	}
	/**
	 * Json转化一个对象
	 * @param obj		要json转化的对象
	 * @return			格式为:"{}"的字符串
	 */
	public String getJson(Object obj){
		StringBuffer json=new StringBuffer();
		try {
			BeanInfo beanInfo=Introspector.getBeanInfo(obj.getClass(),Object.class);
			
			PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
			json.append("{");
			boolean start=false;
			for(PropertyDescriptor pd:pds){
				String value=null;
				Object objTemp=pd.getReadMethod().invoke(obj);
				
				if(objTemp==null){
					continue;
				}
				
				//测试是否有延迟加载
				try {
					value=objTemp.toString();
				} catch (LazyInitializationException e) {
					// TODO Auto-generated catch block
					LOGGER.info(obj.getClass().getName()+"的"+pd.getName()+"属性延迟加载！");
					continue;
				}
				
				if(!start){
					start=true;
				}else{
					json.append(",");
				}
				
				if(Set.class.isInstance(objTemp)){
					Set set=(Set)objTemp;
					json.append(pd.getName()+":"+getJson(set));
				}else if(List.class.isInstance(objTemp)){
					List list=(List)objTemp;
					json.append(pd.getName()+":"+getJson(list));
				}else if(Map.class.isInstance(objTemp)){
					Map map=(Map)objTemp;
					json.append(pd.getName()+":"+getJson(map));
				}else{	
					
					if(boolean.class.equals(pd.getReadMethod().getReturnType())||Boolean.class.equals(pd.getReadMethod().getReturnType())){
						json.append(pd.getName()+":"+value);
						
					}else if(Date.class.equals(pd.getReadMethod().getReturnType())){
						//转换成字符串
						Object date = pd.getReadMethod().invoke(obj);
						
						if(date!=null){
							value = DateTool.getDateString((Date)date);
						}			
						json.append(pd.getName()+":'"+value+"'");
					}
					else{
						json.append(pd.getName()+":'"+value+"'");
					}
				}			
				
			}
			json.append("}");
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return json.toString();
	}
	public String getJson(Set set){
		StringBuffer json=new StringBuffer("[");
		int size=set.size();

		int i=0;
		for(Iterator it=set.iterator();it.hasNext();){
			Object o=it.next();			
			json.append(getJson(o));
			if(i+1!=size){
				json.append(",");
			}
			i++;
		}
		json.append("]");		
		return json.toString();
	}
	/**
	 * Json化对象
	 * @param list			要格式化对象数组
	 * @return				格式为:"[{},{}]"的字符串
	 */
	public String getJson(List list){
		StringBuffer json=new StringBuffer("[");
		int size=list.size();

		int i=0;
		for(Iterator it=list.iterator();it.hasNext();){
			Object o=it.next();
			json.append(getJson(o));
			if(i+1!=size){
				json.append(",");
			}
			i++;
		}
		json.append("]");		
		return json.toString();
	}
	public String getJson(Map map){
		StringBuffer json=new StringBuffer("[");
		int size=map.size();
		if(size==0){
			return null;
		}
		int i=0;
		for(Iterator it=map.entrySet().iterator();it.hasNext();){
			Map.Entry  o=(Map.Entry)it.next();
			json.append(o.getKey()+":'"+o.getValue()+"'");
			if(i+1!=size){
				json.append(",");
			}
			i++;
		}
		json.append("]");		
		return json.toString();
	}
	
	
	/**
	 * Json化对象
	 * @param obj				要Json化的对象
	 * @param strings			对象属性名称数组
	 * @return					格式为:"{}"的字符串
	 */
	public String getJson(T obj,String[] strings ){
		
		if(strings==null||strings.length==0){
			return getJson(obj);
		}
		
		StringBuffer json=new StringBuffer();
		PropertyDescriptor pd=null;
		try {
			json.append("{");
			int j=0;
			for(String str:strings){
				String value=null;
				pd=new PropertyDescriptor(str,obj.getClass());
				if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
					value=pd.getReadMethod().invoke(obj).toString();
				}
				
				json.append(str+":'"+value+"'");
				
				if(j+1!=strings.length){
					json.append(",");
				}
				j++;
			}
			json.append("}");
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return json.toString();
	}
	
	/**
	 * Json化对象
	 * @param obj				要Json化的对象
	 * @param strings			不包括用','隔开的对象属性名称数组
	 * @return					格式为:"{}"的字符串
	 */
	public String getJsonExceptFields(T obj,String[] strings ){
		
		if(strings==null||strings.length==0){
			return getJson(obj);
		}
		
		StringBuffer json=new StringBuffer();
		
		Arrays.sort(strings);
		
		try {
			BeanInfo beanInfo=Introspector.getBeanInfo(obj.getClass(),Object.class);
			
			PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
			json.append("{");
			boolean start=false;
			for(PropertyDescriptor pd:pds){
				String value=null;
				Object objTemp=pd.getReadMethod().invoke(obj);
				
				if(objTemp==null||Arrays.binarySearch(strings,pd.getName())>=0){
					continue;
				}
				
				//测试是否有延迟加载
				try {
					value=objTemp.toString();
				} catch (LazyInitializationException e) {
					// TODO Auto-generated catch block
					LOGGER.info(obj.getClass().getName()+"的"+pd.getName()+"属性延迟加载！");
					continue;
				}
				
				if(!start){
					start=true;
				}else{
					json.append(",");
				}
				
				if(Set.class.isInstance(objTemp)){
					Set set=(Set)objTemp;
					json.append(pd.getName()+":"+getJson(set));
				}else if(List.class.isInstance(objTemp)){
					List list=(List)objTemp;
					json.append(pd.getName()+":"+getJson(list));
				}else if(Map.class.isInstance(objTemp)){
					Map map=(Map)objTemp;
					json.append(pd.getName()+":"+getJson(map));
				}else{	
					value=objTemp.toString();
					if("boolean".equals(pd.getReadMethod().getReturnType().getName())){
						json.append(pd.getName()+":"+value);
						
					}else{
						
						json.append(pd.getName()+":'"+value+"'");
					}
				}			
				
			}
			json.append("}");
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return json.toString();
	}
	/**
	 * Json化对象
	 * @param obj				要Json化的对象
	 * @param strings			不包括的对象属性名称数组
	 * @return					格式为:"{}"的字符串
	 */
	public String getJsonExceptFields(T obj,String strings ){
		if(strings==null){
			return this.getJson(obj);
		}
		String[] array=strings.split(",");
		if(array.length==0){
			return this.getJson(obj);
		}else{
			return this.getJsonExceptFields(obj, array);
		}
	}
	/**
	 * Json化对象
	 * @param list				要格式化对象数组
	 * @param strings			对象属性名称数组
	 * @param objIntervalMark	对象间隔符
	 * @param startMark			开始符
	 * @param endMark			结束符
	 * @return					格式为:"startMark{}objIntervalMark{}endMark"的字符串
	 */
	public String getJson(List<T> list,
						String[] strings,
						String objIntervalMark,
						String startMark,
						String endMark ){
		StringBuffer json=new StringBuffer();
		PropertyDescriptor pd=null;
		int i=0;
		json.append(startMark);
		try {
			for(T obj:list){
				json.append("{");
				int j=0;
				for(String str:strings){
					String value=null;
					pd=new PropertyDescriptor(str,obj.getClass());
					if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
						value=pd.getReadMethod().invoke(obj).toString();
					}
					
					json.append(str+":'"+value+"'");
					
					if(j+1!=strings.length){
						json.append(",");
					}
					j++;
				}
				if(i+1==list.size()){
					json.append("}");
				}else{
					json.append("},");
				}
				i++;
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		json.append(endMark);
		return json.toString();
	}
	
	/**
	 * 数组化
	 * @param list			要格式化对象数组
	 * @param strings		对象属性名称数组
	 * @return				格式为:"[[],[]]"的字符串
	 */
	public String getArray(List<T> list,String[] strings){
		StringBuffer json=new StringBuffer();
		PropertyDescriptor pd=null;
		int i=0;
		json.append("[");
		try {
			for(T obj:list){
				json.append("[");
				int j=0;
				for(String str:strings){
					String value=null;
					pd=new PropertyDescriptor(str,obj.getClass());
					if(pd!=null&&pd.getReadMethod().invoke(obj)!=null){
						value=pd.getReadMethod().invoke(obj).toString();
					}
					
					json.append("'"+value+"'");
					
					if(j+1!=strings.length){
						json.append(",");
					}
					j++;
				}
				if(i+1==list.size()){
					json.append("]");
				}else{
					json.append("],");
				}
				i++;
			}
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e){
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		json.append("]");
		return json.toString();
	}
	
	/**
	 * 返回失败信息
	 * @param info
	 * @return
	 */
	public static String getFormFailJson(String info){
		StringBuffer sb=new StringBuffer("{success: false," +
				"errors:'" +info+
		"'}");
		return sb.toString();
	}
	/**
	 * 表单成功返回除了一些字段外的信息
	 * @param obj
	 * @param strings
	 * @return
	 */
	public String getFormSuccessJsonExceptFields(T obj,String[] strings){
		String content = this.getJsonExceptFields(obj, strings);
		return getFormSuccessJson(content);
	}
	public String getFormSuccessJsonExceptFields(T obj,String strings){
		String content = this.getJsonExceptFields(obj, strings);
		return getFormSuccessJson(content);
	}
	private String getFormSuccessJson(String strings){
		StringBuffer content=new StringBuffer();
		content.append("{success: true,")
				.append("data:")
				.append(strings)
				.append("}");
		return content.toString();
	}
	/**
	 * 把json数据转化为map
	 * @param jsonString
	 * @return
	 */
	public Map getJsonToMap(String jsonString){
		Map map=new HashMap();
		jsonString=jsonString
					.substring(
						jsonString.indexOf("{")+1,
						jsonString.indexOf("}"));
		
		String[] strs=jsonString.split(",");
		for(String str:strs){
			String[] sons=str.split(":");
			map.put(sons[0].substring(1, sons[0].length()-1), sons[1].substring(1, sons[1].length()-1));
		}
		return map;
	}
	public String getJsonAjaxSuccess(Object obj){
		StringBuffer content=new StringBuffer();
		content.append("{success: true,");
		content.append("data:"+this.getJson(obj));
		content.append("}");
		return content.toString();
	}
	/**
	 * 解析json
	 * @param json		json字符串
	 * @return
	 */
	public Map<String ,Object> parseJson(String json){
		Map<String,Object> map = new HashMap<String,Object>();
		try {
			JSONObject jObj = new JSONObject(json);
			
			for(Iterator it = jObj.sortedKeys();it.hasNext();){
				String key=(String)it.next();
				map.put(key, jObj.get(key));
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return map;
	}
	/**
	 * 解析json，并封装到对象中
	 * @param json		json字符串
	 * @param bean		要封装的对象
	 * @return
	 */
	public Object parseJson(String json,Object bean){
		
		try {
			JSONObject jObj = new JSONObject(json);
			
			bean=BeanUtil.copyProperties(bean, jObj);
			
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return bean;
	}
	/**
	 * 解析json，并封装到对象数组中
	 * @param json		json字符串
	 * @param clazz		要封装的对象
	 * @return
	 */
	public List<AssociateTableInfo> parseJsonArray(String json){
		List<AssociateTableInfo> list = new ArrayList<AssociateTableInfo>();
		try {
			JSONArray jsonA = new JSONArray(json);
						
			for(int i=0;i<jsonA.length();i++){
				JSONObject jObj = jsonA.getJSONObject(i);
				
				AssociateTableInfo ati = new AssociateTableInfo();
				String clazz=jObj.getString("className");
				clazz=ClassDelegate.clazzMap.get(clazz);
				ati.setClassName(jObj.getString("className"));
				ati.setAssociatedName(jObj.getString("associatedName"));
				//读取bean中的数据
				if(jObj.has("bean")){
					JSONObject jObjBean = jObj.getJSONObject("bean");
					Object bean=Class.forName(clazz).newInstance();			
					BeanUtil.copyProperties(bean, jObjBean);
					ati.setBean(bean);
				}
					
				
				if(jObj.has("map")){
					//读取map中的数据放到map中
					JSONObject jObjMap = jObj.getJSONObject("map");
					Map map = new HashMap();
					for(Iterator it=jObjMap.sortedKeys();it.hasNext();){
						String key=(String)it.next();
						Object value=jObjMap.get(key);
						map.put(key, value);
					}
					ati.setMap(map);
				}
				
				list.add(ati);
			}
					
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
	/**
	 * 解析json，并封装到对象数组中
	 * @param json		json字符串
	 * @param clazz		要封装的对象
	 * @return
	 */
	public List parseJsonArray(String json,Class clazz){
		List list = new ArrayList();
		try {
			JSONArray jsonA = new JSONArray(json);
						
			for(int i=0;i<jsonA.length();i++){
				JSONObject jObj = jsonA.getJSONObject(i);
				
				Object obj = clazz.newInstance();
				
				BeanUtil.copyProperties(obj , jObj);
				
				list.add(obj);
			}
					
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
}
